home *** CD-ROM | disk | FTP | other *** search
- // Real-time Transparent Motion-blurred phong environment mapping
- // Rex Deathstar/WaterLogic, July 1995
- // email me : deathstr@singnet.com.sg
- // BBS HQ : Developer's Site BBS (065-561-0237)
-
- // released to FTP.CDROM.COM and Developer's Site BBS (Singapore)
-
- // remember to read the README.1ST file! :)
-
- // Use SPACEBAR to start/stop your object from rotating and see how the
- // motion blur work its magic.
-
- // TO COMPILE :
- // Use Borland C/C++ v3.1 and Small memory model, turn off all compiler
- // optimizations (it sux anyway :)
-
- // IMPORTANT! :
- // These codes are really not what I'd call 'nice, well-behaved, concise'.
- // There're no comments, too many global variables, no dynamic memory
- // allocation, polygon code has no clipping and no sub-pixelling, and I used
- // the BSWAP 486 instruction for the fun of it, the 3D rotation has low
- // accuracy and is only on 2-axis, no aspect ratio adjustment, inaccurate
- // sorting.
- // The fact that it was written SOOO long ago, and becoz it was my first
- // attempt in 3D, please forgive me :)
- // The only things I think you can learn from this code are the motion blur,
- // transparency and arcsine corrected environment mapping.
- //
- // IMPORTANT! :
- // This code is for READING purposes, not to be cut and pasted into your
- // own demo/program/whatever. Doing so will qualify you as a $uperlemur, and
- // you'd have BETRAYED the TRUST of all who releases source codes for the
- // benefit of others, and it will make us decide not to release more source
- // codes and therefore all who want to learn will hate you. :)
-
- // To Scene95:
- // yes, this is another left out routine from <u know what demo> :)
-
- // Greetings time! :
- // C:> dir/w/s *.* | greet.exe
-
- // Special Dedication! :
- // brandon shen/pandemonium : nope, you got no rights to ban anyone from any
- // demo party unless you're god :)
- // and sorry, you cant make me withdraw
- // from scene 96 unless you're my dad ;)
- // yes, i hope u win something unless i'm not ur
- // friend :P
- // (yes i'm dead serious)
-
- // trepaan : fuck you for writing a trojan virus demo! u made so many people
- // suffer needlessly!
- // iguana : love you for all your help and belief that releasing source codes
- // does work :)
- // ARM : thank you for all the enlightenment
- // jmagic : thank you for all your inspirations
- // orange : admire you for all the creativity
- // wili : owe you for all your tremendous help
- // MFX : worship you for the first realtime raytraced demo
-
- // Special Tributes! :
- // .....Complex/Orange/Halcyon/NoooN/CNCD/Plant/KLF/Iguana/MFX/Valhalla.....
-
- // WaterLogic productions
- //===========================================================================
- //............................Year 1994......................................
- //1. REXINTRO.ZIP....debut selftro
-
- //2. ASYLUM!.ZIP ....Advert for Asylum BBS (closed down now :( )
-
- //3. ICHIBAN!.ZIP....Advert for IchiBan BBS
-
- //4. ANARCHY!.ZIP....Advert for Anarchy Online BBS
-
- //5. ICHIBAN2.ZIP....2nd Advert for IchiBan BBS
-
- //6. COROM.ZIP ....Advert for COROM PRODUCTIONS BBS
-
- //...........................Year 1995.......................................
- //7. _FACES.ZIP ....Slideshow demo featuring realtime crossfading
-
- //8. TINIFIRE.ZIP....76 byte fire routine, real small huh? (Full sources)
-
- //9. TINYSTAR.ZIP....123 byte 3D starfield, another small one. (Full sources)
-
- //10. DELAYDOT.ZIP....3D object morph with delaydots. (Full sources)
-
- //11. PARTICLE.ZIP....3D Lissajous figures morph. (Full sources)
-
- //12. PURENESS.ZIP....1st place megademo during 'The Scene 95' demo party at
- // Seaview Hotel/Singapore on 2nd July 1995.
-
- //13. COROMSRC.ZIP....Source codes to a BBS advert
-
- //14. WATERFAL.ZIP....Source codes to a waterfall effect as seen in REXINTRO.
-
- //............................Year 1996......................................
- //15. PLASWARP.ZIP....Source codes to the plasma and image warp effect as
- // seen in Pureness (needs PURENESS.DAT to run)
-
- //16. DEVSITE!.ZIP....BBS advert for Developer's Site BBS, now WaterLogic's
- HQ. Features SVGA 3D motion blur.
-
- //16. AGEN-ART.ZIP....High-res JPGs of Agen's art seen in Pureness
-
- //17. STARGATE.ZIP....Source codes to the texture-mapped wormhole seen
- // in Pureness.
-
- //18. MODELIST.ZIP....Generic VESA graphic mode lister with sources in C
-
- //19. VOXELSPC.ZIP....Source codes to a fast height&color interpolated
- // Voxel landscape routine
-
- //20. MPHONG.ZIP......Full sources to transparent motion-blur phong effect
-
- //21. D???????.ZIP....Megademo for 'The Scene 96'!
- // Will be released on 2nd June 1996.
- // Features my new demo system 'EXP24'
-
-
-
- #pragma inline
- asm .486
-
-
- #include <conio.h>
- #include <math.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <dos.h>
- #include <process.h>
-
- //-Phong parameters-//
- float SPECULIAR_COEF; // Speculiar coefficient
- float SPECULIAR_EXPONENT; // Speculiar exponent
- float DIFFUSE ; // Diffuse coefficient
- float AMBIENCE ; // Ambient light amount
- //------------------//
-
- int _3DXFORM=1; // Flag to do 3D rotations
- #define MAXVERTEX 750
- #define MAXFACE 1400
- #define rad 0.01745329
- #define MAX 1300 // 3D rotation angle resolution
- #define START_SCANLINE 0 // Screen scanline to start render
- #define END_SCANLINE 200 // Screen scanline to end render
- #define X 0
- #define Y 1
- #define Z 2
- #define LEFT_ENTRY 0
- #define RITE_ENTRY 4
- #define unitScale 127.0 // scale of unit vector
- #define pixelScale 191.0 // No.of colors used in palette
- #define arccos_size 256
- #define VERTEXfile "VERTEX.DAT"
- #define FACETfile "FACET.DAT"
- #define VNORMfile "VNORM.DAT"
- #define PALfile "EPHONGM.PAL"
- #define NBINS 400
- #define BINSIZE 64
- #define BINSIZELOG2 6
- #define BLUR_LEVEL 1
- #define MATRIX3D_RESOLUTION 10
-
- char palette[768],phong[768],bmp_palette[1024];
-
- unsigned int vbuffer,order,backdrop,texture,alpha,vram=0xa000;
- int a,b,c,d,n,v,temp,dummy,loop_length;
- int wait,wait2,nframes,*temp_ptr;
-
- int VERTEX,FACE; //No.of Vertices and Facets in object
- int object[MAXVERTEX][3];
- int pt[MAXVERTEX][4],facet[MAXFACE][3],current_bin;
- long vnorm32[MAXVERTEX][3];
- int vnorm[MAXVERTEX][3],vnorm2[MAXVERTEX][3],*vnormal;
- char arccos[arccos_size],asine[256];
-
- unsigned int idx,idx1,idx2,y_offset[200],phong_curve[256],jmptable[256];
- int dud1[350],slope[800],dud2[350],top,bot,ysize;
- int p1x,p1y,p2x,p2y,p3x,p3y,flipflop;
- int v1,v2,w1,w2,i1,i2,i3;
-
- int sinf[MAX],cosf[MAX],xsin,xcos,ysin,ycos,zsin,zcos;
- int temp_x,temp_y,temp_z;
- int rx,ry,rz,rx_dir,ry_dir,rz_dir,key;
- int DDAtx,DDAty,texture_x,texture_y,DDAx;
-
- asm backdrop_file db 'phong7-1.bmp',0
- //asm texture_file db 'texture.dat',0
- asm texture_file db 'envmap.bmp',0
- #define BMP
-
- //#define BLACK_BACKDROP
- #define BLACK_VALUE 0
-
- //||||||||||||||||||
- //||| PROTOTYPES |||
- //||||||||||||||||||
- void graphics();
- void text();
- void init3d_10bits();
- void make_phong_table();
- void load_object();
- void do_3D_transformation();
- void sort_facets();
- void move_light_source();
- void draw_object_envmap();
- void calc_slope();
- void show_buffer();
- void debug();
- void load_texture();
- void load_backdrop();
- void apply_env_map_coord();
-
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- //||| MAIN FUNCTION |||
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- void main()
- {
- if(allocmem(4096,&vbuffer)!=-1) exit(1);
- if(allocmem(4096,&order)!=-1) exit(1);
- if(allocmem(4000,&backdrop)!=-1) exit(1);
- if(allocmem(4096,&texture)!=-1) exit(1);
- if(allocmem(4096,&alpha)!=-1) exit(1);
-
- load_object();
- load_texture();
- load_backdrop();
-
- #ifndef BMP
- puts("RealTime 3D renderer using Metal Environment mapping");
- puts("Rex Deathstar, July 1995");
- printf("\nEnter Speculiar Coefficient:");
- scanf("%f",&SPECULIAR_COEF);
- printf("\nEnter Speculiar Exponent:");
- scanf("%f",&SPECULIAR_EXPONENT);
- printf("\nEnter Diffuse Component:");
- scanf("%f",&DIFFUSE);
- printf("\nEnter Ambience amount:");
- scanf("%f",&AMBIENCE);
- #endif
-
- init3d_10bits();
- make_phong_table();
- randomize();
- graphics();
-
- //---------------------------MAIN LOOP-------------------------------------
- MAIN_LOOP:;
- while(!kbhit())
- {
- if(_3DXFORM==1) do_3D_transformation();
- sort_facets();
- apply_env_map_coord();
- draw_object_envmap();
- show_buffer();
- nframes++;
- }
- //-------------------------------------------------------------------------
- key=getch();
- if(key==' ') { _3DXFORM*=-1; goto MAIN_LOOP; }
- asm mov ax,3
- asm int 0x10
-
- printf("No.of frames drawn:%d",nframes);
- }
-
- //|||||||||||||||||||||||||||||||||||
- //||| COPY VIRTUAL BUFFER TO VRAM |||
- //|||||||||||||||||||||||||||||||||||
- void show_buffer()
- {
- //copy buffer to screen
- asm mov dx,0x3da
- vr1:
- asm in al,dx
- asm test al,8
- asm jnz vr1
- /*vr2:
- asm in al,dx
- asm test al,8
- asm jz vr2*/
-
- /*asm mov ax,0xa000
- asm mov es,ax
- asm push ds
- asm mov ds,[vbuffer]
- asm mov cx,64000/4
- asm xor di,di
- asm xor si,si
- asm rep movsd
- asm pop ds
-
- //clear buffer
- asm mov es,[vbuffer]
- asm push ds
- asm mov ds,[backdrop]
- asm mov cx,64000/4
- asm xor di,di
- asm xor si,si
- asm xor eax,eax
- asm rep movsd
- asm pop ds*/
-
- // transparent motion blur,
- // composites 'vbuffer' with 'alpha', then with 'texture'
- asm mov di,64000
- asm mov es,[alpha]
- asm mov fs,[backdrop]
- asm mov gs,[vram]
- asm push ds
- asm mov ds,[vbuffer]
- asm xor cx,cx
-
- composite:
- asm mov ax,[di] // get 2 pixels from 'vbuffer'
- asm mov dx,es:[di] // get 2 pixels from 'alpha'
- asm mov bx,dx
-
- //PIXEL #1
- asm and al,al // is this pixel drawn? (during phongfill())
- asm jz skipper0 // nope, skip it
- asm add bl,al // composite with pixel in 'alpha'
- asm rcr bl,1 // average it, rcr=2 cycles on 486
- asm mov [di],cl // clear 'vbuffer'
-
- skipper0:
- // motion blur, reduce intensity of expired samples
- asm sub bl,BLUR_LEVEL
- asm jnc not_negative0 // less than zero?
- asm xor bl,bl // overflow, clear pixel
- not_negative0:
-
-
- //PIXEL #2
- asm and ah,ah // is this pixel drawn? (during phongfill())
- asm jz skipper1 // nope, skip it
- asm add bh,ah // composite with pixel in 'alpha'
- asm rcr bh,1 // average it
- asm mov [di+1],cl // clear 'vbuffer'
-
- skipper1:
- // motion blur, reduce intensity of expired samples
- asm sub bh,BLUR_LEVEL
- asm jnc not_negative1 // less than zero?
- asm xor bh,bh // overflow, clear pixel
- not_negative1:
-
- asm mov es:[di],bx // store back to 'alpha'
- // now composite with texture, directly to 'vram'
- asm add bx,fs:[di] // pixelScale=192, textureScale=64
- asm mov gs:[di],bx // so max=255, no overflow
-
- asm sub di,2
- asm jnc composite
- asm pop ds
- }
-
-
- //||||||||||||||||||||||||||||||||||
- //||| 3D ROTATION ALONG Y,Z AXIS |||
- //||||||||||||||||||||||||||||||||||
- void do_3D_transformation()
- {
- asm mov bx,[rx]
- asm shl bx,1
- asm mov ax,sinf[bx]
- asm mov bx,cosf[bx]
- asm mov [xsin],ax
- asm mov [xcos],bx
-
- asm mov bx,[ry]
- asm shl bx,1
- asm mov ax,sinf[bx]
- asm mov bx,cosf[bx]
- asm mov [ysin],ax
- asm mov [ycos],bx
-
- // transform vertices
- asm lea di,[pt]
- asm lea si,[object]
- asm mov cx,MATRIX3D_RESOLUTION
- asm mov ax,[VERTEX]
- asm mov [a],ax
-
- xform3D:
- // X-axis rotate
- //temp_y= (*ypt * cosf[xdeg] + *zpt * sinf[xdeg]) >> 7;
- //temp_z= (*zpt * cosf[xdeg] - *ypt * sinf[xdeg]) >> 7;
- asm mov ax,[si+2]
- asm imul [xcos]
- asm mov bx,dx
- asm mov cx,ax
-
- asm mov ax,[si+4]
- asm imul [xsin]
- asm add cx,ax
- asm adc bx,dx
-
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_y],cx
-
-
- asm mov ax,[si+4]
- asm imul [xcos]
- asm mov bx,dx
- asm mov cx,ax
-
- asm mov ax,[si+2]
- asm imul [xsin]
- asm sub cx,ax
- asm sbb bx,dx
-
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_z],cx
-
-
- // Y-axis rotate
- //temp_x= (*xpt * cosf[ydeg] - *zpt * sinf[ydeg]) >> 7;
- //temp_z= (*xpt * sinf[ydeg] + *zpt * cosf[ydeg]) >> 7;
- asm mov ax,[si]
- asm imul [ycos]
- asm mov bx,dx
- asm mov cx,ax
-
- asm mov ax,[temp_z]
- asm imul [ysin]
- asm sub cx,ax
- asm sbb bx,dx
-
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_x],cx
-
-
- asm mov ax,[si]
- asm imul [ysin]
- asm mov bx,dx
- asm mov cx,ax
-
- asm mov ax,[temp_z]
- asm imul [ycos]
- asm add cx,ax
- asm adc bx,dx
-
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_z],cx
-
- asm mov [di+4],cx
-
-
- // Perspective transform
- asm movsx ebx,[temp_z]
- asm add ebx,512
- asm neg ebx
-
- asm movsx eax,[temp_x]
- asm sal eax,9
- asm cdq
- asm idiv ebx
- asm add ax,160
- asm mov [di],ax
-
- asm movsx eax,[temp_y]
- asm sal eax,9
- asm cdq
- asm idiv ebx
- asm add ax,100
- asm mov [di+2],ax
-
- asm add si,6
- asm add di,8
- asm dec [a]
- asm jz xformDone
- asm jmp xform3D
- xformDone:
-
-
- // transform vertex normals
- asm lea di,[vnorm2]
- asm lea si,[vnorm]
- asm mov cx,MATRIX3D_RESOLUTION
- asm mov ax,[VERTEX]
- asm mov [a],ax
-
- xform3D_vnorm:
-
- // X-axis rotate
- //temp_y= (*ypt * cosf[xdeg] + *zpt * sinf[xdeg]) >> 7;
- //temp_z= (*zpt * cosf[xdeg] - *ypt * sinf[xdeg]) >> 7;
- asm mov ax,[si+2]
- asm imul [xcos]
- asm mov bx,dx
- asm mov cx,ax
- asm mov ax,[si+4]
- asm imul [xsin]
- asm add cx,ax
- asm adc bx,dx
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_y],cx
-
- asm mov ax,[si+4]
- asm imul [xcos]
- asm mov bx,dx
- asm mov cx,ax
- asm mov ax,[si+2]
- asm imul [xsin]
- asm sub cx,ax
- asm sbb bx,dx
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_z],cx
-
-
- // Y-axis rotate
- //temp_x= (*xpt * cosf[ydeg] - *zpt * sinf[ydeg]) >> 7;
- //temp_z= (*xpt * sinf[ydeg] + *zpt * cosf[ydeg]) >> 7;
- asm mov ax,[si]
- asm imul [ycos]
- asm mov bx,dx
- asm mov cx,ax
- asm mov ax,[temp_z]
- asm imul [ysin]
- asm sub cx,ax
- asm sbb bx,dx
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_x],cx
-
- asm mov ax,[si]
- asm imul [ysin]
- asm mov bx,dx
- asm mov cx,ax
- asm mov ax,[temp_z]
- asm imul [ycos]
- asm add cx,ax
- asm adc bx,dx
- asm shrd cx,bx,MATRIX3D_RESOLUTION
- asm mov [temp_z],cx
-
-
- asm mov ax,[temp_x]
- asm mov [di],ax
- asm mov ax,[temp_y]
- asm mov [di+2],ax
- asm mov ax,[temp_z]
- asm mov [di+4],ax
-
- asm add si,6
- asm add di,6
- asm dec [a]
- asm jz xformDone_vnorm
- asm jmp xform3D_vnorm
- xformDone_vnorm:
-
-
- if( (ry+=ry_dir)>=MAX ) ry=0;
- if( (rx+=rx_dir)>=MAX ) rx=0;
- if(!wait2--) { wait2=60; ry_dir=random(5)+1; rx_dir=random(5); }
-
-
-
- }
-
- //|||||||||||||||||||||||||||||||||||||||||
- //||| BACKFACE ELIMINATION AND BIN SORT |||
- //|||||||||||||||||||||||||||||||||||||||||
- void sort_facets()
- {
- asm mov fs,[order]
-
- asm mov cx,[FACE]
- asm lea bx,[facet]
- bin_sort:
- asm mov si,[bx] // facet[][0]
- asm mov eax,dword ptr [si]
- asm mov dword ptr [p1x],eax
- asm mov bp,[si+4]
-
- asm mov si,[bx+2] // facet[][1]
- asm mov eax,dword ptr [si]
- asm mov dword ptr [p2x],eax
-
- asm mov si,[bx+4] // facet[][2]
- asm mov eax,dword ptr [si]
- asm mov dword ptr [p3x],eax
-
- // BACKFACE CULLING
- asm mov ax,[p2x]
- asm mov dx,[p3x]
- asm mov di,[p2y]
- asm mov si,[p3y]
- asm sub ax,[p1x] // ax=v1
- asm sub dx,[p1x] // dx=w1
- asm sub di,[p1y] // di=v2
- asm sub si,[p1y] // si=w2
- asm imul ax,si
- asm imul di,dx
- asm sub ax,di // ax=v1*w2-v2*w1
- asm cmp ax,0
- asm jge facet_is_hidden
- // BACKFACE CULL COMPLETE
-
- asm add bp,NBINS/2 // shift z-origin, so all z's are +ve
- asm shl bp,BINSIZELOG2+1
- asm mov ax,fs:[bp] // get facet count in bin
- asm cmp ax,BINSIZE-1
- asm jge bin_is_full
- asm inc fs:[bp] // add facet to bin
- asm add ax,ax // word access
- asm add bp,ax
- asm mov fs:[bp+2],bx // save facet address instead of index
- bin_is_full:
-
- facet_is_hidden:
- asm add bx,6
- asm dec cx
- asm jz sort_done
- asm jmp bin_sort
- sort_done:
- }
-
-
- //|||||||||||||||||||||||||||||||||||||||||||||||||||||
- //||| INITIALIZE GRAPHICS MODE AND LOAD VGA PALETTE |||
- //|||||||||||||||||||||||||||||||||||||||||||||||||||||
- void graphics()
- {
- asm mov ax,13h
- asm int 10h
-
- #ifndef BMP
- asm mov dx,0x3c8
- asm xor ax,ax
- asm out dx,al
- asm inc dx
- asm mov cx,768
- asm lea si,[phong]
- asm cld
- asm rep outsb
- #else
- asm mov dx,0x3c8
- asm xor ax,ax
- asm out dx,al
- asm inc dx
- asm mov cx,768
- asm lea si,[palette]
- asm cld
- asm rep outsb
- #endif
-
-
- for(a=0; a<200; a++)
- y_offset[a]=a*320;
-
- #ifndef BMP
- asm mov ax,0xa000
- asm mov es,ax
- asm lea si,[phong_curve]
- asm mov di,192
- draw_phong_curve:
- asm lodsw
- asm mov bx,ax
- asm add bx,bx
- asm mov bx,y_offset[bx]
- asm mov byte ptr es:[di+bx],255
- asm mov ax,192
- asm sub ax,di
- asm mov es:[di+320*195],al
- asm mov es:[di+320*196],al
- asm mov es:[di+320*197],al
- asm mov es:[di+320*198],al
- asm dec di
- asm jnz draw_phong_curve
-
- getch();
- #endif
-
- // clear bin table
- asm mov es,[order]
- asm xor di,di
- asm xor eax,eax
- asm mov cx,64000/4
- asm rep stosd
- // clear vbuffer
- asm mov es,[vbuffer]
- asm xor di,di
- asm xor eax,eax
- asm mov cx,64000/4
- asm rep stosd
- }
- //-----------------
- void text()
- {
- asm mov ax,3
- asm int 10h
- }
-
- //|||||||||||||||||||||||||||||||||||||||||||
- //||| PHONG SHADE INTENSITY LOOK-UP TABLE |||
- //|||||||||||||||||||||||||||||||||||||||||||
- void make_phong_table()
- {
- int iL;
- float cos_theta;
-
- for(a=0; a<=pixelScale; a++)
- {
- cos_theta=cos((pixelScale-a)/pixelScale*90.0*rad);
-
- iL=(float)(AMBIENCE
- +DIFFUSE*cos_theta
- +SPECULIAR_COEF*pow(cos_theta,SPECULIAR_EXPONENT))*pixelScale;
-
- phong[a*3+0]=palette[iL*3+0]; // map from linear external palette
- phong[a*3+1]=palette[iL*3+1]; // to phong palette using
- phong[a*3+2]=palette[iL*3+2]; // illumination value, iL.
-
- phong_curve[a]=pixelScale-iL;
- }
-
-
- for(a=192*3; a<256*3; a++)
- phong[a]=palette[a];
-
- for(a=0; a<arccos_size; a++)
- arccos[a]=acos(-2.0*a/arccos_size+1.0)*(pixelScale/M_PI);
-
- }
-
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||
- //||| LOAD OBJECT VERTICES,FACETS AND VERTEX NORMALS |||
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||
- void load_object()
- {
- FILE *f;
-
- f=fopen(VERTEXfile,"rb");
- fseek(f,-2L,SEEK_END);
- fread(&VERTEX,1,2,f); // Get number of vertices
- if(VERTEX>MAXVERTEX) { VERTEX=MAXVERTEX; }
- fseek(f,0,SEEK_SET);
- fread(object,1,VERTEX*3*2,f);
- fclose(f);
-
- f=fopen(FACETfile,"rb");
- fseek(f,-2L,SEEK_END);
- fread(&FACE,1,2,f); // Get number of facets
- if(FACE>MAXFACE) { FACE=MAXFACE; }
- fseek(f,0,SEEK_SET);
- fread(facet,1,FACE*3*2,f);
- fclose(f);
-
- f=fopen(VNORMfile,"rb");
- fread(vnorm32,1,VERTEX*3*4,f);
- fclose(f);
-
- f=fopen(PALfile,"rb");
- fread(palette,1,768,f);
- fclose(f);
-
- printf("\n%d vertices loaded.\n%d facets loaded\n",VERTEX,FACE);
-
- // changing 'facet[][]' to hold vertex address instead of vertex no.
- for(a=0; a<FACE; a++)
- {
- temp_ptr=&pt[facet[a][0]][0];
- asm mov ax,[temp_ptr]
- asm mov [temp],ax
- facet[a][0]=temp;
-
- temp_ptr=&pt[facet[a][1]][0];
- asm mov ax,[temp_ptr]
- asm mov [temp],ax
- facet[a][1]=temp;
-
- temp_ptr=&pt[facet[a][2]][0];
- asm mov ax,[temp_ptr]
- asm mov [temp],ax
- facet[a][2]=temp;
- }
-
- for(a=0; a<VERTEX; a++)
- {
- vnorm[a][X]=vnorm32[a][X];
- vnorm[a][Y]=vnorm32[a][Y];
- vnorm[a][Z]=vnorm32[a][Z];
- }
- }
- //-----------------
- void load_backdrop()
- {
- asm mov ax,0x3d00
- asm lea dx,[backdrop_file]
- asm int 0x21
- asm mov bp,ax
-
- asm mov bx,bp
- asm mov ax,0x4200
- asm xor cx,cx
- asm mov dx,1078
- asm int 0x21
-
- asm mov bx,bp
- asm mov ah,0x3f
- asm mov cx,64000
- asm xor dx,dx
- asm push ds
- asm mov ds,[backdrop]
- asm int 0x21
- asm pop ds
-
- asm mov bx,bp
- asm mov ah,0x3e
- asm int 0x21
-
- //post process backdrop, uses last 64 colors in palette
- asm mov es,[backdrop]
- asm xor di,di
- asm mov cx,64000
- post_process:
- //asm add byte ptr es:[di],192
- asm inc di
- asm loop post_process
-
- #ifdef BLACK_BACKDROP
- asm mov es,[backdrop]
- asm xor di,di
- asm mov al,BLACK_VALUE
- asm mov cx,64000
- //asm rep stosb
- #endif
-
- }
- //---------------------
- void load_texture()
- {
- // LOAD OBJECT TEXTURE
- asm mov ax,0x3d00
- asm lea dx,[texture_file]
- asm int 0x21
- asm mov bp,ax
-
- #ifdef BMP
- asm mov bx,bp
- asm mov ax,0x4200
- asm xor cx,cx
- asm mov dx,54
- asm int 0x21
-
- asm mov bx,bp
- asm mov ah,0x3F
- asm mov cx,1024
- asm lea dx,[bmp_palette]
- asm int 0x21
- #endif
-
- asm mov bx,bp
- asm mov ah,0x3f
- asm mov cx,0x8000
- asm xor dx,dx
- asm push ds
- asm mov ds,[texture]
- asm int 0x21
- asm pop ds
- asm mov bx,bp
- asm mov ah,0x3f
- asm mov cx,0x8000
- asm mov dx,0x8000
- asm push ds
- asm mov ds,[texture]
- asm int 0x21
- asm pop ds
-
- asm mov bx,bp
- asm mov ah,0x3e
- asm int 0x21
-
-
- asm mov es,[texture]
- asm xor di,di
- asm mov bx,3
- maximize:
- asm xor ax,ax
- asm mov al,es:[di]
- asm mul bl
- asm shr ax,2
- asm mov es:[di],al
-
- asm inc di
- asm jnz maximize
-
- #ifndef BMP
- // post process texture
- asm mov es,[texture]
- asm mov bx,1
- asm mov cl,11
- ntimes:
- asm xor di,di
- asm xor dx,dx
- post_process2:
- asm xor ax,ax
- asm xor dx,dx
-
- asm mov dl,es:[di]
- asm add ax,dx
- asm add ax,dx
- asm add ax,dx
- asm mov dl,es:[di+1]
- asm add ax,dx
- asm mov dl,es:[di-1]
- asm add ax,dx
- asm mov dl,es:[di+256]
- asm add ax,dx
- asm mov dl,es:[di-256]
- asm add ax,dx
-
- asm mov dl,es:[di-257]
- asm add ax,dx
- asm mov dl,es:[di-255]
- asm add ax,dx
- asm mov dl,es:[di+257]
- asm add ax,dx
- asm mov dl,es:[di+255]
- asm add ax,dx
-
- asm div cl
-
- asm mov es:[di],al
- asm inc di
- asm jnz post_process2
-
- asm dec bx
- asm jnz ntimes
- #else
-
- n=0;
- for(a=0; a<1024; a+=4)
- {
- palette[n]=bmp_palette[a+2]>>2;
- palette[n+1]=bmp_palette[a+1]>>2;
- palette[n+2]=bmp_palette[a]>>2;
-
- n+=3;
- }
- #endif
- }
- //---------------------
- void init3d_10bits()
- {
- int degree;
-
- for(degree=0; degree<MAX; degree++)
- {
- sinf[degree]=sin(360.0/MAX*degree*rad) * pow(2,MATRIX3D_RESOLUTION);
- cosf[degree]=cos(360.0/MAX*degree*rad) * pow(2,MATRIX3D_RESOLUTION);
- }
-
- for(degree=-128; degree<128; degree++)
- asine[degree+128]=255.0*( (M_PI/2+asin(degree/128.0)) /(M_PI/1));
- }
- //--------------------
- void debug()
- {
- for(a=0; a<NBINS; a++)
- {}
- }
-
- //|||||||||||||||||||||||||||||||||||||||||||
- //||| Compute texture domain coord t(u,v) |||
- //||| from vertex normals using inverse |||
- //||| polar-coordinates |||
- //|||||||||||||||||||||||||||||||||||||||||||
- void apply_env_map_coord()
- {
- /*vnormal=&vnorm2[0][X];
-
- for(a=0; a<VERTEX; a++)
- {
- // environment mapping
- texture_x=asine[*vnormal+128];
- texture_y=asine[*(vnormal+1)+128];
- //texture_x=*vnormal+128;
- //texture_y=*(vnormal+1)+128;
- pt[a][3]=(texture_y<<8)+texture_x;
- vnormal+=3;
- }*/
-
- asm lea si,[vnorm2]
- asm lea di,[pt]
- asm add di,6
- asm mov cx,[VERTEX]
- env_map:
- asm mov bx,[si]
- asm mov al,asine[bx+128]
- asm mov bx,[si+2]
- asm mov ah,asine[bx+128]
-
- asm mov [di],ax
- asm add si,6
- asm add di,8
- asm dec cx
- asm jnz env_map
-
-
- }
-
- //||||||||||||||||||||||||||||||||||||||
- //||| DRAW ALL FACETS STORED IN BINS |||
- //||||||||||||||||||||||||||||||||||||||
- void draw_object_envmap()
- {
- //draw facets onto buffer
- asm mov fs,[order]
- asm mov gs,[texture]
- for(c=NBINS-1; c>=0; c--) // start with the furthest bin
- {
- asm mov si,[c]
- asm shl si,BINSIZELOG2+1
- asm mov [current_bin],si
- asm mov ax,fs:[si] // order[c][0]=number of facets in this bin
- asm mov [d],ax
- asm mov fs:[si],0 // clear bin
-
- order_loop:
- asm cmp [d],0 // all facets in bin drawn?
- asm jg bin_not_empty // not yet, bin still not empty
- asm jmp order_done
- bin_not_empty:
- asm mov ax,[d]
- asm dec [d] // take another facet out of bin
- asm mov si,[current_bin]
- asm add ax,ax
- asm add si,ax
- asm mov si,fs:[si] // facet start address=order[c][d+1];
-
- // GET VERTICES OF CURENT FACET
- asm mov bx,[si] // facet[][0]
- asm mov di,[si+2] //ax=vv1=facet[][1]
- asm mov si,[si+4] //ax=vv2=facet[][2]
-
- // bx=vertex1, di=vertex2, si=vertex3
-
- // SORT FACET EDGES
- // make p1 the top-most point
- asm mov ax,[bx+2]
- asm cmp ax,[di+2]
- asm jle ok1
- asm xchg bx,di
- ok1:
- asm mov ax,[bx+2]
- asm cmp ax,[si+2]
- asm jle ok2
- asm xchg bx,si
- ok2:
- // make p2 the left-most point
- asm mov ax,[di]
- asm cmp ax,[si]
- asm jle ok3
- asm xchg di,si
- ok3:
-
- asm mov [p1x],bx // vertex #1 offset
- asm mov [p2x],di // vertex #2 offset
- asm mov [p3x],si // vertex #3 offset
-
- // BUILD EDGE TABLE
- asm mov [top],200
- asm mov [bot],0
- asm mov bx,[p1x] // vertex offset
- asm mov di,[p3x]
- asm mov cx,[bx] //p1x
- asm mov bp,[bx+2] //p1y
- asm mov ax,[di] //p3x
- asm mov dx,[di+2] //p3y
- asm mov si,[bx+6] //i1
- asm mov di,[di+6] //i3
- asm mov [flipflop],RITE_ENTRY
- asm call make_edge_env // construct edge connecting p1<->p3
-
- asm mov bx,[p1x]
- asm mov di,[p2x]
- asm mov cx,[bx]
- asm mov bp,[bx+2]
- asm mov ax,[di]
- asm mov dx,[di+2]
- asm mov si,[bx+6]
- asm mov di,[di+6]
- asm mov [flipflop],LEFT_ENTRY
- asm call make_edge_env // construct edge connecting p1<->p2
-
- asm mov bx,[p2x]
- asm mov di,[p3x]
- asm mov bp,[bx+2]
- asm mov dx,[di+2]
-
- asm cmp bp,dx
- asm jl ok4
- asm je edge_table_done
- asm xchg bx,di
- asm xchg bp,dx
- asm mov [flipflop],RITE_ENTRY
- ok4:
- asm mov cx,[bx]
- asm mov ax,[di]
- asm mov si,[bx+6]
- asm mov di,[di+6]
- asm call make_edge_env // construct edge connecting p2<->p3
-
- edge_table_done:
- asm mov ax,[top]
- asm mov bx,[bot]
- asm cmp ax,START_SCANLINE
- asm jge top_ok
- asm mov ax,START_SCANLINE
- top_ok:
- asm cmp bx,END_SCANLINE
- asm jle bot_ok
- asm mov bx,END_SCANLINE
- bot_ok:
- asm mov cx,bx
- asm sub cx,ax
- asm jc skip_facet // skip if length is negative
- asm jz skip_facet // skip if length is zero
- asm call draw_one_facet_env
- skip_facet:
- asm jmp order_loop
- order_done:
- }
- }
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- //||| FILL DOUBLE-EDGE TABLE USING DIGITAL DIFFERENTIAL ANALYSIS |||
- //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- void calc_slope()
- {
- asm make_edge_env:
- asm mov bx,dx
- asm sub bx,bp // ysize=ye-ys;
- asm jnz okok
- asm jmp done
- okok:
- asm mov [ysize],bx
-
- asm mov bx,bp
- asm shl bx,3 // each entry is 8 bytes
- asm add bx,offset [slope] // idx=ys<<3+&slope;
- asm add bx,[flipflop] // left/rite entry selector
-
- // record top and bottom of current edge
- asm cmp [top],bp //if(top>ys) top=ys;
- asm jle top_nochange
- asm mov [top],bp
- top_nochange:
- asm cmp [bot],dx //if(bot<ye) bot=ye;
- asm jge bot_nochange
- asm mov [bot],dx
- bot_nochange:
-
- asm mov dx,cx
- asm shl edx,7+16 // x1=xs<<7; 7-bit becoz x can be 0..320
-
- asm sub ax,cx
- asm shl ax,7
- asm mov cx,[ysize]
- asm cwd
- asm idiv cx // xadd=128*(xe-xs)/ysize;
- asm push ax
-
-
- asm mov ax,di
- asm xor al,al
- asm mov dx,si
- asm xor dl,dl
- asm sub ax,dx
- asm cwd
- asm idiv cx
- asm shl eax,16 // DDAty
-
- asm mov ax,di
- asm xor ah,ah
- asm mov dx,si
- asm xor dh,dh
- asm sub ax,dx
- asm shl ax,8
- asm cwd
- asm idiv cx
- asm mov edi,eax // DDAtx
-
- asm mov ax,si
- asm shl ax,8
- asm mov [texture_x],ax
- asm mov ax,si
- asm xor al,al
- asm mov [texture_y],ax
-
- asm pop ax
- asm shl eax,16
-
- fill_slope_table:
- asm mov dh,byte ptr [texture_y+1]
- asm mov dl,byte ptr [texture_x+1]
- asm mov [bx],edx
- asm add bx,8
- asm add edx,eax
- asm add dword ptr [texture_x],edi
-
- asm dec cx
- asm jnz fill_slope_table
- done:;
- asm ret
- }
- //||||||||||||||||||||||||||||
- //||| FILL ONE PHONG FACET |||
- //||||||||||||||||||||||||||||
- void fillshape_env()
- {
-
- asm draw_one_facet_env:
- asm mov bx,ax // bx=top
- asm add bx,bx // word access
- asm mov bp,y_offset[bx]
- asm shl bx,2 // qword access
- asm add bx,offset [slope]
- asm mov es,[vbuffer]
-
- // fill scanlines in poly from top to bottom
- fill_loop:
- asm bswap ecx
-
- // left entry
- asm mov cx,[bx] //angle1
- asm mov di,[bx+2] //x1
- asm shr di,7 //remove fix-point
- // rite entry
- asm mov ax,[bx+4] //angle2
- asm mov si,[bx+6] //x2
- asm shr si,7 //remove fix-point
- asm add bx,8 //next entry...
-
- // let's go from left to right
- asm cmp si,di //xsize=x2-x1
- asm jnz proceed //xsize=0?
- asm jmp far ptr done_one_scanline //xsize is zero, no fill done
- proceed:
- asm jnc no_exchange //xsize<0?
- asm xchg si,di
- asm xchg cx,ax //switch angle1,angle2
- no_exchange:
- asm sub si,di
-
- asm push ax
- asm sub al,cl
- asm shl ax,8
- asm cwd
- asm idiv si
- asm shl eax,16
-
- asm pop ax
- asm sub ah,ch
- asm xor al,al
- asm cwd
- asm idiv si
-
- asm push ds
- asm mov ds,[texture]
-
- asm xor dx,dx
- asm mov dh,ch
- asm mov [texture_x],dx
- asm mov dh,cl
- asm mov [texture_y],dx
-
- asm add di,bp
- asm push bx
-
- envmap_innerloop:
- asm mov bl,byte ptr [texture_x+1]
- asm mov bh,byte ptr [texture_y+1]
- asm mov dl,gs:[bx]
-
- asm mov es:[di],dl
- asm inc di
-
- asm add dword ptr [texture_x],eax
- asm dec si
- asm jnz envmap_innerloop
-
- asm pop bx
- asm pop ds
- done_one_scanline:
- asm add bp,320 //start of next scanline
-
- asm bswap ecx
- asm dec cx
- asm jz facet_filled
- asm jmp fill_loop
- facet_filled:
- asm ret
-
- asm innerloop_start:
-
- asm mov bl,byte ptr [texture_x+1]
- asm mov bh,byte ptr [texture_y+1]
- asm mov al,gs:[bx]
- asm add dword ptr [texture_x],edx
- asm mov es:[di],al
- asm inc di
-
- asm innerloop_end:
- }
-